namespace SimpleWebServices.Configuration
{
    using System.Configuration;
    using System.Xml;
    using Xunit;

    public sealed class InternalServerErrorConfigurationFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<InternalServerErrorConfiguration>()
                .DerivesFrom<object>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .Implements<IConfigurationSectionHandler>()
                .Result);
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new InternalServerErrorConfiguration());
        }

        [Fact]
        public void op_Settings()
        {
            Assert.NotNull(InternalServerErrorConfiguration.Settings());
        }

        [Fact]
        public void op_Settings_string()
        {
            Assert.NotNull(InternalServerErrorConfiguration.Settings("simplewebservices/error"));
        }

        [Fact]
        public void op_Create_object_object_XmlNodeNull()
        {
            InternalServerErrorSettings obj = new InternalServerErrorConfiguration().Create(null, null, null as XmlNode) as InternalServerErrorSettings;

            Assert.Null(obj);
        }

        [Fact]
        public void op_Create_object_object_XmlNodeEmpty()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml("<error />");

            InternalServerErrorSettings actual = new InternalServerErrorConfiguration().Create(null, null, xml.DocumentElement) as InternalServerErrorSettings;

            Assert.Null(actual.Notification);
        }

        [Fact]
        public void op_Create_object_object_XmlNode()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(
                "<error enabled='true'>" +
                    "<notification>" +
                        "<from address='webmaster@simplewebservices.org' name='Simple Web Services' />" +
                        "<to>" +
                            "<recipient address='jane.doe@example.com' name='Jane Doe' />" +
                            "<recipient address='john.doe@example.com' name='John Doe' />" +
                        "</to>" +
                    "</notification>" +
                "</error>");

            InternalServerErrorSettings actual = new InternalServerErrorConfiguration().Create(null, null, xml.DocumentElement) as InternalServerErrorSettings;

            Assert.True(actual.Enabled);

            Assert.Equal<string>("webmaster@simplewebservices.org", actual.Notification.From.Address);
            Assert.Equal<string>("Simple Web Services", actual.Notification.From.Name);

            Assert.Equal<int>(2, actual.Notification.To.Count);
            Assert.Equal<string>("jane.doe@example.com", actual.Notification.To[0].Address);
            Assert.Equal<string>("Jane Doe", actual.Notification.To[0].Name);
            Assert.Equal<string>("john.doe@example.com", actual.Notification.To[1].Address);
            Assert.Equal<string>("John Doe", actual.Notification.To[1].Name);
        }

        [Fact]
        public void op_Create_object_object_XmlNodeWithoutNames()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(
                "<error enabled='false'>" +
                    "<notification>" +
                        "<from address='webmaster@simplewebservices.org' />" +
                        "<to>" +
                            "<recipient address='jane.doe@example.com' />" +
                            "<recipient address='john.doe@example.com' />" +
                        "</to>" +
                    "</notification>" +
                "</error>");

            InternalServerErrorSettings actual = new InternalServerErrorConfiguration().Create(null, null, xml.DocumentElement) as InternalServerErrorSettings;

            Assert.False(actual.Enabled);

            Assert.Equal<string>("webmaster@simplewebservices.org", actual.Notification.From.Address);
            Assert.Null(actual.Notification.From.Name);

            Assert.Equal<int>(2, actual.Notification.To.Count);
            Assert.Equal<string>("jane.doe@example.com", actual.Notification.To[0].Address);
            Assert.Null(actual.Notification.To[0].Name);
            Assert.Equal<string>("john.doe@example.com", actual.Notification.To[1].Address);
            Assert.Null(actual.Notification.To[1].Name);
        }

        [Fact]
        public void op_Create_object_object_XmlNodeWithoutFrom()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(
                "<error>" +
                    "<notification>" +
                        "<to>" +
                            "<recipient address='jane.doe@example.com' />" +
                            "<recipient address='john.doe@example.com' />" +
                        "</to>" +
                    "</notification>" +
                "</error>");

            Assert.Throws<ConfigurationErrorsException>(() => new InternalServerErrorConfiguration().Create(null, null, xml.DocumentElement));
        }

        [Fact]
        public void op_Create_object_object_XmlNodeWithoutFromAddress()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(
                "<error>" +
                    "<notification>" +
                        "<from />" +
                        "<to>" +
                            "<recipient address='jane.doe@example.com' />" +
                            "<recipient address='john.doe@example.com' />" +
                        "</to>" +
                    "</notification>" +
                "</error>");

            Assert.Throws<ConfigurationErrorsException>(() => new InternalServerErrorConfiguration().Create(null, null, xml.DocumentElement));
        }

        [Fact]
        public void op_Create_object_object_XmlNodeWithoutTo()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(
                "<error>" +
                    "<notification>" +
                        "<from address='webmaster@simplewebservices.org' />" +
                    "</notification>" +
                "</error>");

            Assert.Throws<ConfigurationErrorsException>(() => new InternalServerErrorConfiguration().Create(null, null, xml.DocumentElement));
        }

        [Fact]
        public void op_Create_object_object_XmlNodeWithoutToRecipient()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(
                "<error>" +
                    "<notification>" +
                        "<from address='webmaster@simplewebservices.org' />" +
                        "<to></to>" +
                    "</notification>" +
                "</error>");

            Assert.Throws<ConfigurationErrorsException>(() => new InternalServerErrorConfiguration().Create(null, null, xml.DocumentElement));
        }

        [Fact]
        public void op_Create_object_object_XmlNodeWithoutToRecipientAddress()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(
                "<error>" +
                    "<notification>" +
                        "<from address='webmaster@simplewebservices.org' />" +
                        "<to>" +
                            "<recipient />" +
                        "</to>" +
                    "</notification>" +
                "</error>");

            Assert.Throws<ConfigurationErrorsException>(() => new InternalServerErrorConfiguration().Create(null, null, xml.DocumentElement));
        }

        [Fact]
        public void op_Create_object_object_XmlNodeInvalid()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml("<bad-name/>");

            Assert.Throws<ConfigurationErrorsException>(() => new InternalServerErrorConfiguration().Create(null, null, xml.DocumentElement));
        }
    }
}